package poi;

import com.alibaba.fastjson.JSONObject;
import constants.TemplateType;
import cookie.ExportTempCookie;
import cookie.ProjectCookie;
import cookie.TemplateSetting;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import util.ProjectUtil;
import util.TemplateUtil;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.*;

/**
 * 用一句话描述该文件作用
 *
 * @Author pengsamkee
 * create at 2016/11/10 15:36
 */
public class ExcelHandlePipeline implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(ExcelHandlePipeline.class);

    private static final String encoding = "UTF-8";

    private Executor fileHandleExecutor;

    private Queue<File> fileHandleQueue;

    private boolean running;

    private long sleepTime;

    private String excelDirectoryPath;

    private ProjectCookie projectCookie;

    public ExcelHandlePipeline(Queue<File> queue, String excelDirectoryPath) {
        this.fileHandleQueue = queue;
        this.excelDirectoryPath = excelDirectoryPath;
        this.running = true;
        this.fileHandleExecutor = new ThreadPoolExecutor(16, 32, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(10 * 16), Executors.defaultThreadFactory());
        this.projectCookie = ProjectCookie.getProjectCookie();
    }

    public void setSleepTime(long sleepTime) {
        this.sleepTime = sleepTime;
    }

    public void run() {
        while (this.running) {
            try {
                if ((fileHandleQueue != null) && (fileHandleQueue.size() > 0)) {
                    ExcelHandleWorker protocolHandleWorker = new ExcelHandleWorker(fileHandleQueue);
                    this.fileHandleExecutor.execute(protocolHandleWorker);
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            }
            try {
                Thread.sleep(this.sleepTime);
            } catch (InterruptedException e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            }
        }
    }

    private final class ExcelHandleWorker implements Runnable {

        private File file;

        private ExcelHandleWorker(Queue<File> fileHandleQueue) {
            this.file = fileHandleQueue.poll();
        }

        public void run() {
            try {
                if (file.isHidden()) {
                    return;
                }
                System.err.println("====================================");
                System.err.println("start handel excel: " + this.file.getAbsolutePath());
                ExcelReader reader = new ExcelReader(file, excelDirectoryPath);

                String clientExportType = projectCookie.getClientExportTemplateName();
                String serverExportType = projectCookie.getServerExportTemplateName();
                List<TemplateSetting> templateSettings = projectCookie.getTemplateSettings();
                TemplateSetting clientTemplateSetting = null;
                TemplateSetting serverTemplateSetting = null;
                for (TemplateSetting templateSetting : templateSettings) {
                    if (templateSetting.getName().equals(clientExportType)) {
                        clientTemplateSetting = templateSetting;
                    }
                    if (templateSetting.getName().equals(serverExportType)) {
                        serverTemplateSetting = templateSetting;
                    }
                }

                if (ExportTempCookie.ExportClient) {
                    if (reader.clientMapDatas.size() > 0) {
                        String clientJson = JSONObject.toJSONString(reader.clientMapDatas);
                        File clientJsonFile;
                        if (reader.packageName.equals("")) {
                            clientJsonFile = new File(clientTemplateSetting.getExportJsonDirectory() + File.separator + reader.fileName.substring(0, 1).toUpperCase() + reader.fileName.substring(1) + ".json");
                        } else {
                            clientJsonFile = new File(clientTemplateSetting.getExportJsonDirectory() + File.separator + reader.packageName + "." + reader.fileName + ".json");
                        }
                        FileUtils.writeStringToFile(clientJsonFile, clientJson, encoding);
                    }

                    HashMap<String, Object> clientTemplateMap = new HashMap<String, Object>();
                    clientTemplateMap.put("className", reader.fileName);
                    clientTemplateMap.put("properties", reader.clientColumnHeaderMap);

                    File clientBeanFile;
                    String clientExportBeanRootPackage = clientTemplateSetting.getExportBeanRootPackage();
                    clientTemplateMap.put("packageName", StringUtils.isEmpty(clientExportBeanRootPackage) ? reader.packageName : clientExportBeanRootPackage + (StringUtils.isEmpty(reader.packageName) ? "" : "." + reader.packageName));
                    clientBeanFile = new File(clientTemplateSetting.getExportBeanDirectory() + File.separator + reader.packagePath + File.separator + reader.fileName.substring(0, 1).toUpperCase() + reader.fileName.substring(1) + "." + clientTemplateSetting.getExtension());
                    TemplateUtil.genFile(clientTemplateMap, FileUtils.readFileToString(ProjectUtil.getTemplateFile(TemplateType.CLIENT, clientExportType), encoding), clientBeanFile, encoding);
                }

                if (ExportTempCookie.ExportServer) {
                    String serverExportBeanRootPackage = serverTemplateSetting.getExportBeanRootPackage();
                    if (reader.serverMapDatas.size() > 0) {
                        String serverJson = JSONObject.toJSONString(reader.serverMapDatas);
                        ConfigEntity entity = new ConfigEntity();
                        File serverJsonFile;
                        String packagePath = StringUtils.isEmpty(serverExportBeanRootPackage) ? reader.packageName : serverExportBeanRootPackage + (StringUtils.isEmpty(reader.packageName) ? "" : "." + reader.packageName);
                        entity.setClassName(packagePath + "." + reader.fileName.substring(0, 1).toUpperCase() + reader.fileName.substring(1));
                        entity.setContent(serverJson);
                        if (reader.packageName.equals("")) {
                            serverJsonFile = new File(serverTemplateSetting.getExportJsonDirectory() + File.separator + reader.fileName.substring(0, 1).toUpperCase() + reader.fileName.substring(1) + ".json");
                        } else {
                            serverJsonFile = new File(serverTemplateSetting.getExportJsonDirectory() + File.separator + reader.packageName + "." + reader.fileName + ".json");
                        }
                        String exportServerJson = JSONObject.toJSONString(entity);
                        FileUtils.writeStringToFile(serverJsonFile, exportServerJson, encoding);
                    }

                    HashMap<String, Object> serverTemplateMap = new HashMap<>();
                    serverTemplateMap.put("className", reader.fileName);
                    serverTemplateMap.put("properties", reader.serverColumnHeaderMap);

                    File serverBeanFile;
                    serverTemplateMap.put("packageName", StringUtils.isEmpty(serverExportBeanRootPackage) ? reader.packageName : serverExportBeanRootPackage + (StringUtils.isEmpty(reader.packageName) ? "" : "." + reader.packageName));
                    serverBeanFile = new File(serverTemplateSetting.getExportBeanDirectory() + File.separator + reader.packagePath + File.separator + reader.fileName.substring(0, 1).toUpperCase() + reader.fileName.substring(1) + "." + serverTemplateSetting.getExtension());
                    TemplateUtil.genFile(serverTemplateMap, FileUtils.readFileToString(ProjectUtil.getTemplateFile(TemplateType.SERVER, serverExportType), encoding), serverBeanFile, encoding);
                }

            } catch (Exception e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            } finally {
            }
        }
    }
}
